/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package es.unavarra.mti.iws.logic.undoredo;

import es.unavarra.mti.iws.Manager;
import java.util.LinkedList;

/**
 *
 * @author Asier
 */
public class UndoManager {
    private int maxRedoOps;
    private Manager manager;

    private final LinkedList<UndoRedoOperation> undo;
    private final LinkedList<UndoRedoOperation> redo;

    public UndoManager(int maxRedoOps,Manager manager) {
        this.maxRedoOps = maxRedoOps;
        this.manager = manager;
        undo = new LinkedList<UndoRedoOperation>();
        redo = new LinkedList<UndoRedoOperation>();
    }


    public synchronized void addOpMerging(UndoRedoOperation op){
        if (undo.isEmpty()){
            addOp(op);
        }else{
            UndoRedoOperation lastOp = undo.pollLast();
            CompositeOperation cop = new CompositeOperation(new UndoRedoOperation[]{lastOp, op});
            undo.add(cop);
            updateUndoMenu();
        }
    }


    public synchronized void addOp(UndoRedoOperation op){
        undo.add(op);
        if(!redo.isEmpty()) { redo.clear(); }
        while (undo.size() > maxRedoOps){
            undo.removeFirst();
        }
        updateUndoMenu();
    }


    public synchronized void undo(){
        if (!undo.isEmpty()){
            UndoRedoOperation op = undo.getLast();
            undo.removeLast();
            op.undo();
            redo.addLast(op);
        }
        updateUndoMenu();
    }

    public synchronized void redo(){
        if(!redo.isEmpty()){
            UndoRedoOperation op = redo.getLast();
            redo.removeLast();
            op.redo();
            undo.addLast(op);
        }
        updateUndoMenu();
    }

    public synchronized void clear(){
        undo.clear();
        redo.clear();
        updateUndoMenu();
    }

    private void updateUndoMenu() {
        int sizeUndo = undo.size();
        int sizeRedo = redo.size();
    
        manager.getFrame().getUndoMenu().setEnabled( sizeUndo > 0);
        manager.getFrame().getRedoMenu().setEnabled( sizeRedo > 0);
        manager.getFrame().setSaved(false);
    }
}
